package cn.edu.gxnu.dsa.gms;

import cn.edu.gxnu.dsa.list.SqList;
import cn.edu.gxnu.dsa.sort.DoubleType;

public class GradeRecordList extends SqList {

	public GradeRecordList(int maxSize) {
		super(maxSize);
	}

	public void quickSort(char sortType) {
		try {
			qSort(0, (this.length() - 1), sortType);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private void qSort(int low, int high, char sortType) throws Exception {
		if (low < high) {
			int pivotLoc = partition(low, high, sortType);
			qSort(low, pivotLoc - 1, sortType);
			qSort(pivotLoc + 1, high, sortType);
		}
	}

	private int partition(int low, int high, char sortType) throws Exception {
		StudentGradeRecord pivot = (StudentGradeRecord) this.get(low);

		while (low < high) {

			switch (sortType) {
			case SystemConstants.SORT_TYPE_CHN:
				while ((low < high) && ((DoubleType) pivot.getChineseGrade())
						.compareTo((DoubleType) ((StudentGradeRecord) this.get(high)).getChineseGrade()) <= 0) {
					high--;
				}
				break;
			case SystemConstants.SORT_TYPE_ENG:
				while ((low < high) && ((DoubleType) pivot.getEnglishGrade())
						.compareTo((DoubleType) ((StudentGradeRecord) this.get(high)).getEnglishGrade()) <= 0) {
					high--;
				}
				break;
			case SystemConstants.SORT_TYPE_MATH:
				while ((low < high) && ((DoubleType) pivot.getMathGrade())
						.compareTo((DoubleType) ((StudentGradeRecord) this.get(high)).getMathGrade()) <= 0) {
					high--;
				}
				break;
			case SystemConstants.SORT_TYPE_SUM:
				while ((low < high) && ((DoubleType) pivot.getSum())
						.compareTo((DoubleType) ((StudentGradeRecord) this.get(high)).getSum()) <= 0) {
					high--;
				}
				break;
			case SystemConstants.SORT_TYPE_AVE:
				while ((low < high) && ((DoubleType) pivot.getAverageGrade())
						.compareTo((DoubleType) ((StudentGradeRecord) this.get(high)).getAverageGrade()) <= 0) {
					high--;
				}
				break;
			case SystemConstants.SORT_TYPE_ID:
				while ((low < high) && ((String) pivot.getStudentNr())
						.compareTo((String) ((StudentGradeRecord) this.get(high)).getStudentNr()) <= 0) {
					high--;
				}
				break;
			case SystemConstants.SORT_TYPE_NAME:
				while ((low < high) && ((String) pivot.getName())
						.compareTo((String) ((StudentGradeRecord) this.get(high)).getName()) <= 0) {
					high--;
				}
				break;
			default:
				System.out.println("!!! Wrong sorting type, teminated!!!");
				return -1;
			}

			if (low < high) {
				set(low, this.get(high));
				low++;
			}

			switch (sortType) {
			case SystemConstants.SORT_TYPE_CHN:
				while ((low < high) && ((DoubleType) pivot.getChineseGrade())
						.compareTo((DoubleType) ((StudentGradeRecord) this.get(low)).getChineseGrade()) > 0) {
					low++;
				}
				break;
			case SystemConstants.SORT_TYPE_ENG:
				while ((low < high) && ((DoubleType) pivot.getEnglishGrade())
						.compareTo((DoubleType) ((StudentGradeRecord) this.get(low)).getEnglishGrade()) > 0) {
					low++;
				}
				break;
			case SystemConstants.SORT_TYPE_MATH:
				while ((low < high) && ((DoubleType) pivot.getMathGrade())
						.compareTo((DoubleType) ((StudentGradeRecord) this.get(low)).getMathGrade()) > 0) {
					low++;
				}
				break;
			case SystemConstants.SORT_TYPE_SUM:
				while ((low < high) && ((DoubleType) pivot.getSum())
						.compareTo((DoubleType) ((StudentGradeRecord) this.get(low)).getSum()) > 0) {
					low++;
				}
				break;
			case SystemConstants.SORT_TYPE_AVE:
				while ((low < high) && ((DoubleType) pivot.getAverageGrade())
						.compareTo((DoubleType) ((StudentGradeRecord) this.get(low)).getAverageGrade()) > 0) {
					low++;
				}
				break;
			case SystemConstants.SORT_TYPE_ID:
				while ((low < high) && ((String) pivot.getStudentNr())
						.compareTo((String) ((StudentGradeRecord) this.get(low)).getStudentNr()) > 0) {
					low++;
				}
				break;
			case SystemConstants.SORT_TYPE_NAME:
				while ((low < high) && ((String) pivot.getName())
						.compareTo((String) ((StudentGradeRecord) this.get(low)).getName()) > 0) {
					low++;
				}
				break;
			default:
				System.out.println("!!! Wrong sorting type, teminated!!!");
				return -1;
			}

			if (low < high) {
				set(high, this.get(low));
				high--;
			}
		}

		set(low, pivot);
		return low;
	}

	private void set(int index, Object obj) {
		(this.getListElement())[index] = obj;
	}

}
